﻿namespace ufida.u9.ait.openapi
{
	using System;
	using System.Collections.Generic;
	using System.Text;
    using ufida.u9.ait.openapi.utils;
    using UFIDA.U9.Base;
    using UFIDA.U9.Base.Currency;
    using UFIDA.U9.Base.Organization;
    using UFIDA.U9.Base.UOM;
    using UFIDA.U9.CBO.HR.Department;
    using UFIDA.U9.CBO.HR.Operator;
    using UFIDA.U9.CBO.Pub.Controller;
    using UFIDA.U9.CBO.SCM.Customer;
    using UFIDA.U9.CBO.SCM.Item;
    using UFIDA.U9.CBO.SCM.ProjectTask;
    using UFIDA.U9.SM.SC;
    using UFSoft.UBF.AopFrame;
    using UFSoft.UBF.Business;
    using UFSoft.UBF.Util.Context;

	/// <summary>
	/// SaleContractSaveSV partial 
	/// </summary>	
	public partial class SaleContractSaveSV 
	{	
		internal BaseStrategy Select()
		{
			return new SaleContractSaveSVImpementStrategy();	
		}		
	}
	
	#region  implement strategy	
	/// <summary>
	/// Impement Implement
	/// 
	/// </summary>	
	internal partial class SaleContractSaveSVImpementStrategy : BaseStrategy
	{
		public SaleContractSaveSVImpementStrategy() { }

		public override object Do(object obj)
		{						
			SaleContractSaveSV bpObj = (SaleContractSaveSV)obj;
            try
            {
				if (bpObj.Data == null || bpObj.Data.Count == 0)
					throw new Exception("传入参数为空");
				List<CommonArchiveDataDTOData> retlist = new List<CommonArchiveDataDTOData>();

				foreach(var dto in bpObj.Data)
                {
					if (String.IsNullOrEmpty(dto.DocNo))
						throw new Exception("必须传入单号[DocNo]");

					SaleContract doc = SaleContract.Finder.Find($"DocNo='{dto.DocNo}'");
					if(doc == null)
                    {
						//新增逻辑
						doc=CreateDoc(dto);
						//修改单号
						using (ISession session = Session.Open())
						{
							doc.DocNo = dto.DocNo;
							session.Commit();
						}
						//审核
						doc = ApproveDoc(doc);
						//返回值
						CommonArchiveDataDTOData ret = new CommonArchiveDataDTOData()
						{
							ID = doc.ID,
							Code = doc.DocNo,
						};
						retlist.Add(ret);
					}
                    else
                    {
						//修改逻辑
						//throw new AITException(599, $"单号:{dto.DocNo}已经存在,不能生成!");
						//支持对表头日期和扩展字段的修改,审核后也可以
						doc = UpdateDoc(doc, dto);

						//返回值
						CommonArchiveDataDTOData ret = new CommonArchiveDataDTOData()
						{
							ID = doc.ID,
							Code = doc.DocNo,
						};
						retlist.Add(ret);
					}
				}

				return ResultUtils.success(bpObj, bpObj.Data, retlist);
			}
			catch(Exception ex)
            {
				return ResultUtils.error(bpObj, bpObj.Data, ex);
			}
		}

        private SaleContract UpdateDoc(SaleContract doc, SaleContractAITDTOData dto)
        {
            using(ISession session = Session.Open())
            {
				//日期处理
				if (!String.IsNullOrEmpty(dto.StartDate))
				{
					doc.StartDate = DateTime.Parse(dto.StartDate);
				}
				if (!String.IsNullOrEmpty(dto.EndDate))
				{
					doc.EndDate = DateTime.Parse(dto.EndDate);
				}

				//扩展字段处理
				if (dto.DescFlexField != null)
				{
					doc.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
					DTOUtils.DTOPropCopy(dto.DescFlexField, doc.DescFlexField);
				}

				//其他字段
				doc.Memo = dto.Memo;

				session.Commit();
            }

			return doc;
        }

        private SaleContract ApproveDoc(SaleContract doc)
        {
            using(ISession session = Session.Open())
            {
				doc.Status = SCStatusEnum.Approved;
				foreach(var line in doc.SaleContractLines)
                {
					line.Status = SCStatusEnum.Approved;
                }

				session.Commit();
            }

			return doc;
        }

        private SaleContract CreateDoc(SaleContractAITDTOData dto)
        {
			SaleContract doc = null;

			using (ISession session = Session.Open())
			{
				doc = CreateHead(dto);
				doc = CreateLines(doc, dto);

				session.Commit();
			}
			return doc;
        }

        private SaleContract CreateLines(SaleContract doc, SaleContractAITDTOData dto)
        {
			int rowno = 0;
            foreach(var linedto in dto.SaleContractLines)
            {
				rowno += 10;

				SCLine line = SCLine.Create(doc);
				//行号
				if (linedto.DocLineNo > 0)
					line.DocLineNo = linedto.DocLineNo;
				else
					line.DocLineNo = rowno;

				//扩展字段处理
				if (linedto.DescFlexField != null)
				{
					line.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
					DTOUtils.DTOPropCopy(linedto.DescFlexField, line.DescFlexField);
				}

				//组织
				line.SupplyOrg = doc.Org;
				line.ShipperOrg = doc.Org;
				line.CurrentOrg = doc.Org;

                //料品/分类/计量单位
                if (linedto.ItemInfo != null)
                {
                    ItemMaster item = EntityUtils.GetEntityByCode<ItemMaster>(linedto.ItemInfo.ItemCode);
					line.ItemInfo = new ItemInfo();
					line.ItemInfo.ItemID = item;
					line.ItemInfo.ItemCode = item.Code;
					line.ItemInfo.ItemName = item.Name;
                }
				line.ItemDesc = linedto.ItemDesc;
				//line.ItemCategory = EntityUtils.GetEntityByCode<ItemCategory>(linedto.ItemCategory);
				if (linedto.ItemCategory != null)
                {
					//取分类体系包含 销售 的料品分类
					line.ItemCategory = EntityUtils.GetEntityByPath<ItemCategory>($"Code='{linedto.ItemCategory.Code}' and CategorySystem.IsSale=1");
					line.TradeUOM = line.ItemCategory.CategoryUOM;
				}
				if (line.ItemInfo.ItemID != null)
                {
					line.TradeUOM = line.ItemInfo.ItemID.SalesUOM;
                }
                if(linedto.TradeUOM != null)
                {
					line.TradeUOM = EntityUtils.GetEntityByCode<UOM>(linedto.TradeUOM.Code);
				}
                if (line.TradeUOM != null)
                {
					line.TradeBasicUOM = line.TradeUOM.BaseUOM;
					line.PriceUOM = line.TradeUOM;
					line.PriceBasicUOM = line.TradeBasicUOM.BaseUOM;
				}
				
				//数量 单价 价税合计
				line.ContactQtyPU = linedto.ContactQtyPU;
				line.ContactQtyTU = linedto.ContactQtyPU;
				line.DeliveryQtyTU = linedto.ContactQtyPU;

				line.OrderPrice = linedto.OrderPrice;//不含税
				line.TaxRate = doc.TaxRate;
                if (line.ContactQtyPU > 0 && line.OrderPrice > 0)
                {
					//无税金额
					line.NetTaxMnyTC = line.ContactQtyPU * line.OrderPrice;

					//价税合计
					line.TotalMnyTC = line.ContactQtyPU* line.OrderPrice*(1+line.TaxRate);
					line.TotalMnyFC = line.TotalMnyTC;
					line.TotalMnyAC = line.TotalMnyTC;

					//税额
					line.TaxMnyTC = line.TotalMnyTC - line.NetTaxMnyTC;
				}
				

				//其他
				line.Project = EntityUtils.GetEntityByCode<Project>(linedto.Project);
				line.TUToTBURate = 1;
				line.TBUTOPBURate = 1;
				line.TBMainUOMToSubUOM = 1;
				line.PUTOPBURate = 1;
				line.IsPreRecChangeable = true;
				line.TaxSchedule = doc.TaxSchedule;
				line.StateMachineID = Guid.Empty;
				line.StartDate = doc.StartDate;
				line.BillToSite = doc.BillToSite;
				line.SeibanAlterable = UFIDA.U9.CBO.SCM.Enums.SeibanAlterableEnum.GetFromValue(2);
				line.Memo = linedto.Memo;
				line.ReceivalTerm = doc.Payer.RecervalTerm;//收款条件
			}

			return doc;
        }

        private SaleContract CreateHead(SaleContractAITDTOData dto)
        {
			SaleContract doc = SaleContract.Create();

			doc.DocNo = dto.DocNo;

			//扩展字段处理
			if (dto.DescFlexField != null)
			{
				doc.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
				DTOUtils.DTOPropCopy(dto.DescFlexField, doc.DescFlexField);
			}

			//组织
			if (dto.Org == null)
			{
				doc.Org = Context.LoginOrg;
			}
			else
			{
				doc.Org = EntityUtils.GetEntityByCode<Organization>(dto.Org);
			}
			doc.LegacyOrg = doc.Org;
			doc.ExeOrg = doc.Org;
			doc.BalanceOrg = doc.Org;
			doc.AccOrg = doc.Org;

			//币种
			if (dto.TC == null)
			{
				dto.TC = new CopyOfCommonArchiveDataDTOData
				{
					Code = "C001"
				};
			}
			doc.TC = EntityUtils.GetEntityByCode<Currency>(dto.TC);
			doc.FC = doc.TC;
			doc.AC = doc.TC;
			doc.TCToACExchRateType = ExchangeRateTypesEnum.Empty;

			//日期处理
			if (!String.IsNullOrEmpty(dto.StartDate))
			{
				doc.StartDate = DateTime.Parse(dto.StartDate);
			}
			if (!String.IsNullOrEmpty(dto.EndDate))
			{
				doc.EndDate = DateTime.Parse(dto.EndDate);
			}
            if (!String.IsNullOrEmpty(dto.BusinessDate))
            {
				doc.BusinessDate = DateTime.Parse(dto.BusinessDate);
            }

			//客户信息
			if (dto.OrderBy == null)
				throw new Exception("必须传入订货客户[OrderBy]");
			doc.OrderBy = EntityUtils.GetEntityByCode<Customer>(dto.OrderBy.Code);
			doc.Payer = doc.OrderBy;
			if(doc.OrderBy.CustomerSites!=null&& doc.OrderBy.CustomerSites.Count > 0)
            {
				doc.BillToSite = doc.OrderBy.CustomerSites[0];
				doc.PayerSite = doc.OrderBy.CustomerSites[0];
			}
			doc.ARTerm = doc.OrderBy.ARConfirmTerm;
			doc.TaxSchedule=doc.OrderBy.TaxSchedule;
			if (doc.TaxSchedule == null)
				throw new Exception($"客户[{doc.OrderBy.Code}],不存在税组合");
			doc.TaxRate = doc.TaxSchedule.TaxScheduleTaxs[0].Tax.TaxRate;

			//其他
			doc.Dept = EntityUtils.GetEntityByCode<Department>(dto.Dept);
			doc.Seller = EntityUtils.GetEntityByCode<Operators>(dto.Seller);
			doc.SCDocType = EntityUtils.GetEntityByCode<SCDocType>(dto.SCDocType);
			doc.SaleContractType = EntityUtils.GetEntityByCode<SaleContractType>(dto.SaleContractType);
			doc.TCToFCExchRate = 1;
			doc.TCToACExchRate = 1;
			doc.Memo = dto.Memo;
			doc.IsPriceIncludeTax = dto.IsPriceIncludeTax;
			return doc;
		}
    }

	#endregion
	
	
}